package sasp_messages;


import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import java.util.Arrays;

public class CommCipher {

	private SecretKey key;
	private Cipher aesCipher;
        //private int cipherTextLength = 64;
        private int ivLength = 16;

	private void setKey(SecretKey _key)	{
		key = _key;
	}

	public SecretKey getKey()	{
		return key;
	}

        private byte[] concatBytes(byte[] _iv, byte[] _m)   {
            byte[] _ivAndMessage = Arrays.copyOf(_iv, _iv.length+_m.length);
            System.arraycopy(_m, 0, _ivAndMessage, _iv.length, _m.length);
            return _ivAndMessage;
        }

        private byte[] getIV(byte[] _ivAndMessage)  {
            byte[] _iv = new byte[ivLength];
            System.arraycopy(_ivAndMessage, 0, _iv, 0, ivLength);
            return _iv;
        }

        private byte[] getCipherText(byte[] _ivAndMessage)  {
            byte[] _cipherText = new byte[_ivAndMessage.length-16];
            System.arraycopy(_ivAndMessage, 16, _cipherText, 0, _ivAndMessage.length-16);
            return _cipherText;
        }

	private void generateKey() throws NoSuchAlgorithmException	{
		KeyGenerator keyGen = KeyGenerator.getInstance("AES");
		key = keyGen.generateKey();
	}

	public byte[] encrypt(byte[] _m) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidParameterSpecException	{
		aesCipher.init(Cipher.ENCRYPT_MODE, key);
                IvParameterSpec iv = aesCipher.getParameters().getParameterSpec(IvParameterSpec.class);
                byte[] ivBytes = iv.getIV();
                byte[] enc = aesCipher.doFinal(_m);
                byte[] ivAndMessage = this.concatBytes(ivBytes,enc);
                return ivAndMessage;
	}

	public String decrypt(byte[] _c) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException	{
                IvParameterSpec _iv = new IvParameterSpec(this.getIV(_c));
                byte[] _cipher = this.getCipherText(_c);
		aesCipher.init(Cipher.DECRYPT_MODE, key, _iv);
		byte[] dec = aesCipher.doFinal(_cipher);
                return new String(dec);
	}

        private void createCipher() throws NoSuchAlgorithmException, NoSuchPaddingException {
                aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        }

	public CommCipher(SecretKey _key) throws NoSuchAlgorithmException, NoSuchPaddingException	{
                this.createCipher();
		this.setKey(_key);
	}

	public CommCipher() throws NoSuchAlgorithmException, NoSuchPaddingException	{
                this.createCipher();
		this.generateKey();
	}



}
